#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Mon Jun  9 15:14:15 2025

@author: fenghongli
"""
#构建 PMFG 核心传染网络

import pandas as pd
import numpy as np
import networkx as nx
import matplotlib.pyplot as plt


# 读取贡献矩阵（FEVD已标准化，非对称）
df = pd.read_csv("dy_spillover_matrix.csv", index_col=0)

# 将其转为对称矩阵：保留 max(i→j, j→i)
sym_matrix = df.combine(df.T, func=np.maximum)

# 确保对角为0
np.fill_diagonal(sym_matrix.values, 0)

# 保存为对称版（可视化）
sym_matrix.to_csv("pmfg_sym_spillover_matrix.csv")
print("构建对称溢出矩阵完成")



# 构建无向图对象
G_pmfg = nx.Graph()

# 添加节点
for node in sym_matrix.columns:
    G_pmfg.add_node(node)

# 添加边
edges = []

for i in sym_matrix.index:
    for j in sym_matrix.columns:
        if i != j:
            weight = sym_matrix.loc[i, j]
            edges.append((i, j, weight))

# 按权重从大到小排序，保留 PMFG 所需边数（最多 3N-6 条）
N = len(sym_matrix)
edges_sorted = sorted(edges, key=lambda x: x[2], reverse=True)
top_edges = edges_sorted[:3 * N - 6]

# 添加边
G_pmfg.add_weighted_edges_from(top_edges)
print(f"构建 PMFG 网络完成：保留 {len(top_edges)} 条最强边")




# 位置布局
pos = nx.spring_layout(G_pmfg, seed=42)

# 边权可视化
edge_weights = [G_pmfg[u][v]['weight'] * 10 for u, v in G_pmfg.edges]
node_size = 800

plt.figure(figsize=(10, 8))
nx.draw_networkx_nodes(G_pmfg, pos, node_size=node_size, node_color='skyblue')
nx.draw_networkx_edges(G_pmfg, pos, width=edge_weights, edge_color='gray', alpha=0.6)
nx.draw_networkx_labels(G_pmfg, pos, font_size=10)

plt.title("PMFG Core risk contagion network", fontsize=16)
plt.axis('off')
plt.tight_layout()
plt.savefig("pmfg_core_network.png", dpi=300)
plt.show()
